package com.tudouji.project.harvest.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.flow.service.pojo.BasePojo;
import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.flow.FlowTempNode;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.IFlowBaseService;
import com.flow.service.process.service.impl.CallBackParameterWrapper;
import com.flow.service.process.service.impl.FlowProcessProxy;
import com.github.pagehelper.PageHelper;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.*;
import com.tudouji.common.utils.http.HarvestAnalysisUtils;
import com.tudouji.common.utils.http.HttpBusinessUtils;
import com.tudouji.common.utils.sql.SqlUtil;
import com.tudouji.framework.config.DwlConfig;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.framework.web.page.PageDomain;
import com.tudouji.framework.web.page.TableSupport;
import com.tudouji.project.arealand.domain.TArealand;
import com.tudouji.project.arealand.mapper.TArealandMapper;
import com.tudouji.project.bill.domain.AutoTransfer;
import com.tudouji.project.bill.domain.Whinfo;
import com.tudouji.project.bill.domain.Whinform;
import com.tudouji.project.bill.domain.Whinformitem;
import com.tudouji.project.bill.mapper.WhinformitemMapper;
import com.tudouji.project.bill.service.IAutoTransferService;
import com.tudouji.project.bill.service.impl.WhinfoServiceImpl;
import com.tudouji.project.bill.service.impl.WhinformServiceImpl;
import com.tudouji.project.flow.service.impl.FlowtempnodeServiceImpl;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.harvest.domain.*;
import com.tudouji.project.harvest.mapper.*;
import com.tudouji.project.harvest.service.IFreightorderService;
import com.tudouji.project.organization.domain.Organization;
import com.tudouji.project.organization.domain.Supplier;
import com.tudouji.project.organization.mapper.OrganizationMapper;
import com.tudouji.project.organization.mapper.SupplierMapper;
import com.tudouji.project.permission.domain.Salespermission;
import com.tudouji.project.permission.service.ISalespermissionService;
import com.tudouji.project.product.domain.Productinfo;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.mapper.ProductinfoMapper;
import com.tudouji.project.product.mapper.SalesspecificationMapper;
import com.tudouji.project.quality.domain.Qaitems;
import com.tudouji.project.quality.domain.Qamain;
import com.tudouji.project.quality.domain.Qarecord;
import com.tudouji.project.quality.domain.Qastandard;
import com.tudouji.project.quality.mapper.QastandardMapper;
import com.tudouji.project.quality.service.impl.QamainServiceImpl;
import com.tudouji.project.quality.service.impl.QarecordServiceImpl;
import com.tudouji.project.store.domain.Stockunit;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.domain.Storeroom;
import com.tudouji.project.store.mapper.StockunitMapper;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.store.mapper.StoreroomMapper;
import com.tudouji.project.store.service.impl.StockunitServiceImpl;
import com.tudouji.project.system.domain.SysDept;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.mapper.SysDeptMapper;
import com.tudouji.project.system.mapper.SysUserMapper;
import com.tudouji.project.system.service.ISysConfigService;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import com.tudouji.project.weigh.domain.WeightData;
import com.tudouji.project.weigh.domain.WeightInterfaceParam;
import com.tudouji.project.weigh.service.IWeightInterfaceParamService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

//import com.alibaba.excel.EasyExcel;
//import com.alibaba.excel.ExcelWriter;
//import com.alibaba.excel.write.metadata.WriteSheet;

/**
 * 货运单Service业务层处理
 *
 * @author wf
 * @date 2021-01-18
 */
@Slf4j
@Service
public class FreightorderServiceImpl implements IFreightorderService, IFlowBaseService {
    @Autowired
    private FreightorderMapper freightorderMapper;
    @Autowired
    private ProcurementcontractMapper procurementcontractMapper;
    @Autowired
    private ISalespermissionService permissionService;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private FlowProcessProxy processProxy;
    @Autowired
    private StoreroomMapper storeroomMapper;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private WhinfoServiceImpl whinfoService;
    @Autowired
    private TArealandMapper arealandMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private ProductinfoMapper productinfoMapper;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private QamainServiceImpl qamainService;
    @Autowired
    private QaformServiceImpl qaformService;
    @Autowired
    private QaresultServiceImpl qaresultService;
    @Autowired
    private QarecordServiceImpl qarecordService;
    @Autowired
    private QastandardMapper qastandardMapper;
    @Autowired
    private DpriceApplyMapper dpriceApplyMapper;
    @Autowired
    private ContstandardMapper contstandardMapper;
    @Autowired
    private ForderstandardMapper forderstandardMapper;
    @Autowired
    private OpLocationMapper opLocationMapper;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private SalesspecificationMapper salesspecificationMapper;
    @Autowired
    private StockunitMapper stockunitMapper;

    @Autowired
    private StockunitServiceImpl stockunitService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IAutoTransferService autoTransferService;

    @Autowired
    private SupplierMapper supplierMapper;
    @Autowired
    private WhinformServiceImpl whinformService;
    @Autowired
    private WhinformitemMapper whinformitemMapper;
    @Autowired
    private WeightSystemDataMapper weightSystemDataMapper;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IWeightInterfaceParamService weightInterfaceParamService;
    @Autowired
    private FlowtempnodeServiceImpl iFlowtempnodeService;
    @Autowired
    private IFreightorderService freightorderService;

    private static WeightInterfaceParam weightInterfaceParam;
    /**
     * 查询货运单
     *
     * @param guid 货运单ID
     * @return 货运单
     */
    @Override
    public Freightorder selectFreightorderDetailById(String guid) {
        return freightorderMapper.selectFreightorderDetailById(guid);
    }

    @Override
    public Freightorder selectFreightorderDetailByAutoId(Long guid) {
        return freightorderMapper.selectFreightorderDetailByAutoId(guid);
    }

    /**
     * 查询货运单
     *
     * @param guid 货运单ID
     * @return 货运单
     */
    @Override
    public Freightorder selectFreightorderById(String guid) {
        return freightorderMapper.selectFreightorderById(guid);
    }

    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (com.tudouji.common.utils.StringUtils.isNotNull(pageNum) && com.tudouji.common.utils.StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    /**
     * 查询货运单列表
     *
     * @param freightorder 货运单
     * @return 货运单
     */
    @Override
    public List<Freightorder> selectFreightorderList(Freightorder freightorder, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        if (freightorder == null) {
            freightorder = new Freightorder();
        }
        if (StringUtils.isNotBlank(status)) {
            // 待处理
            if (status.equals("00")) {
                startPage();
                freightorder.setCreateBy(sysUser.getUserId());
                return freightorderMapper.selectApplyPendingList(freightorder);
            } else {
                String[] sts = status.split(",");
                Integer[] stss = (Integer[]) ConvertUtils.convert(sts, Integer.class);
                freightorder.setStats(stss);
            }
        }

        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return freightorderMapper.selectFreightorderList(freightorder);
        } else {
            freightorder.setCondition("none");
            freightorder.setCreateBy(sysUser.getUserId());
            //部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");
            if (permissions.size() > 0) {
                String[] departids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    departids[i] = permissions.get(i).getDepartid();
                }
                freightorder.setDepartids(departids);
            }
            //库房权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            if (permissions.size() > 0) {
                String[] strguids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    strguids[i] = permissions.get(i).getSrguid();
                }
                freightorder.setStrguids(strguids);
            }
            startPage();
            return freightorderMapper.selectFreightorderList(freightorder);
        }
    }
    @Override
    public Freightorder selectFreightorderListSum(Freightorder freightorder, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        if (freightorder == null) {
            freightorder = new Freightorder();
        }

        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            return freightorderMapper.selectFreightorderListSum(freightorder);
        } else {
            freightorder.setCondition("none");
            freightorder.setCreateBy(sysUser.getUserId());
            //部门权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "2");
            if (permissions.size() > 0) {
                String[] departids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    departids[i] = permissions.get(i).getDepartid();
                }
                freightorder.setDepartids(departids);
            }
            //库房权限
            permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "7");
            if (permissions.size() > 0) {
                String[] strguids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    strguids[i] = permissions.get(i).getSrguid();
                }
                freightorder.setStrguids(strguids);
            }
            return freightorderMapper.selectFreightorderListSum(freightorder);
        }
    }

    @Override
    public List<FreightorderExport> selectFreightorder(FreightorderExport freightorder) {
        return freightorderMapper.selectFreightorder(freightorder);
    }


    /**
     * 新增货运单
     *
     * @param freightorder 货运单
     * @return 结果
     */
    @Override
    public int insertFreightorder(Freightorder freightorder) {
        return freightorderMapper.insertFreightorder(freightorder);
    }

    /**
     * 修改货运单
     *
     * @param freightorder 货运单
     * @return 结果
     */
    @Override
    public int updateFreightorder(Freightorder freightorder) {
        return freightorderMapper.updateFreightorder(freightorder);
    }

    /**
     * 批量删除货运单
     *
     * @param guids 需要删除的货运单ID
     * @return 结果
     */
    @Override
    public int deleteFreightorderByIds(String[] guids) {
        return freightorderMapper.deleteFreightorderByIds(guids);
    }

    /**
     * 删除货运单信息
     *
     * @param guid 货运单ID
     * @return 结果
     */
    @Override
    public int deleteFreightorderById(String guid) {
        return freightorderMapper.deleteFreightorderById(guid);
    }

    @Override
    public AjaxResult exportWhinformExport(String guids) {
        /*Freightorder freightorder = freightorderMapper.selectFreightorderById(guids);
        WeightSystemData systemData = new WeightSystemData();
        systemData.setCode(freightorder.getCode());
        List<WeightSystemData> systemDatas = weightSystemDataMapper.selectWeightSystemDataList(systemData);
        if (systemDatas.size() == 0) {
            systemData.setNetWeight(freightorder.getNetWeight());
        } else {
            systemData = systemDatas.get(0);
        }
        String format = "yyyy/MM/dd HH:mm";
        Date createtime = freightorder.getCreatetime();
        String createtimeStr = DateUtils.parseDateToStr(format, createtime);//日期
        String code = freightorder.getCode();//订单编号
        String plantor = freightorder.getPlantor();//发货单位
        String carcode = freightorder.getCarcode();//车号
        String orgname = freightorder.getOrgname();//收货单位

        String title = orgname + "入库单";
        String variety = freightorder.getVariety();//货名
        String specification = freightorder.getSpecification();//规格

        BigDecimal rawWeight = systemData.getRawWeight() == null ? null : systemData.getRawWeight();//毛
        BigDecimal tareWeight = systemData.getTareWeight() == null ? null : systemData.getTareWeight();//皮
        BigDecimal netWeight = freightorder.getSettleweight();//净重

//        BigDecimal deductrate = freightorder.getDeductrate();//扣杂率

        Procurementcontract contract = procurementcontractMapper.selectProcurementcontractById(freightorder.getContractid());
        Qamain qamain = qamainMapper.selectQamainById(contract.getQamainid());
        BigDecimal dianfeng = null;
        if (2 == qamain.getType()) {//淀粉薯质检
            Qaresult qaresult = new Qaresult();
            qaresult.setFoguid(guids);
            dianfeng = qaresultMapper.getDianfengContent(qaresult);//淀粉含量
        }

        BigDecimal price = freightorder.getPrice();//单价
        BigDecimal settlement = freightorder.getSettlement();//金额

        Whinform whinform = new Whinform();
        whinform.setFoguid(guids);
        List<Whinform> whinforms = whinformMapper.selectWhinformList(whinform);
        String overWeightOperator = null;
        String qaOperator = null;
        if (whinforms.size() > 0) {
            overWeightOperator = tuserMapper.selectTuserById(whinforms.get(0).getOperatorid()).getRealname() ;//过磅员 Tuser
        }

        Qaform qaform = new Qaform();
        qaform.setFoguid(guids);
        List<Qaform> qaforms = qaformMapper.selectQaformList(qaform);
        BigDecimal deductrate = null;
        if (qaforms.size() > 0) {
            qaOperator = tuserMapper.selectTuserById(qaforms.get(0).getOperatorid()).getRealname();//化验员 Tuser
            deductrate = qaforms.get(0).getDeductrate();
        }

        Date now = DateUtils.getNowDate();
        String nowStr = DateUtils.parseDateToStr(format, now);//打印时间
        HashMap map = new HashMap();
        map.put("createtimeStr", createtimeStr);
        map.put("code", code);
        map.put("plantor", plantor);
        map.put("carcode", carcode);
        map.put("orgname", orgname);
        map.put("title", title);
        map.put("variety", variety);
        map.put("specification", specification);
        map.put("rawWeight", rawWeight == null ? "XXX":  rawWeight+ "吨");
        map.put("tareWeight", tareWeight == null ? "XXX":  tareWeight + "吨");
        map.put("netWeight", netWeight + "吨");
        map.put("deductrate", deductrate + "%");

        map.put("dianfeng", 2 == qamain.getType() ? dianfeng + "%" : "");
        map.put("price", price + "元");
        map.put("settlement", settlement);
        map.put("settlementStr", Convert.digitUppercase(settlement.doubleValue()));
        map.put("overWeightOperator", overWeightOperator);
        map.put("qaOperator", qaOperator);
        map.put("nowStr", nowStr);
        try {
            print(map, null, code);
            String htmlUrl = PoiExcelToHtmlUtil.excelWriteToHtml(TuDouJiConfig.getDownloadPath(), code, ".xlsx");
            return AjaxResult.success(htmlUrl);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error();
        }*/
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult approval(Long id, Long taskid, String opinion, String fileIds) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
        freightorder.setPlatformId(storeroom.getId());
//        FlowResult result = processUtils.defaultApproval(taskid, fileIds, opinion, freightorder
//                , sysUser);
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, freightorder
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(freightorder.getGuid());
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    /**
     * 20240517
     * 结算单价=订单采收单价的，流程结束，系统不做特殊处理。
     * 结算单价<>订单采收单价的，价格审批后系统做当前采收订单的
     * 原采收单价的返入库、新结算单价的重新入库操作。
     * @param id
     * @param taskid
     * @param opinion
     * @param fileIds
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult conformedPriceApproval(Long id, Long taskid, String opinion, String fileIds) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);
        //查询原入库单
        Whinform inform = new Whinform();
        inform.setFoguid(freightorder.getGuid());
        List<Whinform> informs = whinformService.selectWhinformList(inform);
        inform = informs.get(0);
        //查询入库单明细
        Whinformitem item = new Whinformitem();
        item.setWhinid(inform.getGuid());
        List<Whinformitem> items = whinformitemMapper.selectWhinformitemList(item);

        //原采收单价的返入库
        whinformService.newWhinBack(sysUser, freightorder.getGuid());
        //新结算单价的重新入库
        Whinform entity = prepareItemsWhin(inform.getShrguid(),  freightorder, freightorder.getNetWeight());
        for (Whinformitem it : entity.getItems()) {
            it.setShrguid(items.get(0).getShrguid());
        }
        whinformService.whin(entity, false);

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
        freightorder.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, freightorder
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(freightorder.getGuid());
            pb.setPaystatus(2);
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult conformedPrice(Long id, Long taskid, String opinion, String fileIds, BigDecimal conformedPrice) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);

        Freightorder orderUp = new Freightorder();
        orderUp.setId(id);
        orderUp.setConfirmedPrice(conformedPrice);
        //重新结算
        orderUp.setSettlement(freightorder.getHweight().multiply(conformedPrice).setScale(2, BigDecimal.ROUND_HALF_DOWN));
        orderUp.setActualSettl(conformedPrice);
        freightorderMapper.updateFreightorder(orderUp);

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
        freightorder.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, freightorder
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(freightorder.getGuid());
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult refuse(Long id, String fileIds, String opinion, Long taskid, Long refuseNodeid, Long backUserid) {
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
        freightorder.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.refuse(taskid, fileIds, opinion, freightorder
                , sysUser, refuseNodeid, backUserid);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(freightorder.getGuid());
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult del(Long id) {//修改autoid为id
        Freightorder apply = freightorderMapper.selectFreightorderByAutoId(id);
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        //装车付 未发起过支付申请的  过磅后可进行支付申请
        if (apply.getPaystatus() >= 3) {
            return AjaxResult.error("付款申请已发起！");
        }
        //2023-05-15采收订单删除需要判断如果是扫码拉货的订单需要卸货，解决此司机再次拉货失败的问题
        String wlResult = this.xiehuo(apply.getOrdercode());
        log.info("del freightorder wl's result: " + wlResult);

        Freightorder contract = new Freightorder();
        contract.setId(id);
        contract.setStatus(0);
        freightorderMapper.updateFreightorder(contract);

        //更新待处理任务
        processUtils.updateTaskByOrderId(id, sysUser, Long.valueOf(apply.getFlowId()));
        return AjaxResult.success();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult save(String param, Long contractid, String remark, Long supplierId, String fileIds, Integer sellformPayType) {
//        try {
            if (StringUtils.isNotEmpty(param)) {
                return fromWl(param);
            } else {
                return fromTudou(contractid, remark, supplierId, fileIds,null,null,null,sellformPayType);
            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return AjaxResult.error(e.getMessage());
//        }
    }

    private AjaxResult fromWl(String param) {
        Map<String, String> result = HarvestAnalysisUtils.analysis(param);
        JSONObject json = JSONObject.parseObject(result.get("param"));
        String token = result.get("token");
        String tokenLocal = null;
        try {
            tokenLocal = parseResult(json);
        }catch (Exception e){
            throw new CustomException("进行MD5加密出现错误！");
        }

        AjaxResult ajaxResult = AjaxResult.success();
        if (token.equals(tokenLocal)) {
            /**
             * @auther shaodong
             * @desc 通过采收合同获取相关信息
             * @Date 17:17 2020/8/10
             * @Param []
             * @return void
             **/
            Long contractid = json.getLong("contractid");
            Procurementcontract contract = procurementcontractMapper.selectProcurementcontractByCodeAndStatus(contractid);
            if (contract.getStatus() == null) {
                ajaxResult.put("status", "contracterror");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }

            Freightorder order = setFreightorderData(null, contract);
            order.setOrdercode(json.getString("ordercode"));
            order.setDrivername(json.getString("drivername"));
            order.setDriverphone(json.getString("driverphone"));
            if (StringUtils.isNull(contract.getSupplierId())) {
                ajaxResult.put("status", "noSupplier");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            order.setSupplierId(contract.getSupplierId());
            order.setSupplierName(contract.getSupplierName());
            // 获取种植户名称 20230322 供应商没有绑定用户的情况
            if(contract.getPartb()!=null){
                SysUser user = sysUserMapper.selectUserByGuid(contract.getPartb());
                order.setPlantorid(contract.getPartb());
                order.setPlantor(user.getNickName());
                order.setPlantorphone(user.getPhonenumber());
            }

            if (json.containsKey("carcode")) {
                order.setCarcode(json.getString("carcode"));
            }
            /*if (json.containsKey("amount")) {
                order.setAmount(new BigDecimal(json.getString("amount")));
            }*/
            SysUser operator = sysUserMapper.selectUserByGuid(contract.getOperatorid());
            if (operator != null) {
                order.setCreateBy(operator.getUserId());
                order.setOperatorid(operator.getGuid());
                order.setOperator(operator.getNickName());
            }
            order.setPriceMethod(contract.getPriceMethod());
            freightorderMapper.insertFreightorder(order);

            if (!checkContractWeight(contract.getGuid(), order.getGuid())) {
                //20230224 抛出异常，但是返回物流的状态是否能收到？
                ajaxResult.put("status", "weightout");
//                throw  new CustomException("超过合同规定重量！", 49);
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            String msg = this.save(order, null, operator);
            ajaxResult.put("status", msg);
        } else {
            log.info("-----------签名验证失败---------------");
            ajaxResult.put("status", "signerro");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return ajaxResult;
    }

    /**
     * 解析物流参数，并验证token
     *
     * @param json
     * @return
     * @throws Exception
     */
    private String parseResult(JSONObject json) throws Exception {
        // 验签
        Map<String, String> map = new HashMap<>();
        map.put("orderid", json.getString("orderid"));
        map.put("drivername", json.getString("drivername"));
        map.put("driverphone", json.getString("driverphone"));
        if (json.containsKey("carcode")) {
            map.put("carcode", json.getString("carcode"));
        } else {
            map.put("carcode", null);
        }
        if (json.containsKey("amount")) {
            map.put("amount", json.getString("amount"));
        } else {
            map.put("amount", null);
        }
        map.put("ordercode", json.getString("ordercode"));

        if (json.containsKey("contractid")) {
            map.put("contractid", json.getString("contractid"));
        } else {
            map.put("contractid", null);
        }
        StringBuilder build = new StringBuilder();
        for (Map.Entry<String, String> en : map.entrySet()) {
            build.append(en.getKey() + "=" + en.getValue());
        }
        build.toString();
        String token2 = SecurityUtil.encode(MD5Utils.encryString(build.toString()));
        return token2;
    }

    @Transactional
    public boolean generateFreightOrder(WeightData weightData){
        if(weightData.getOrderId()!=null){
            log.info("seems already generated order Id is :"+weightData.getOrderId());
            return false;
        }
        //获取合同

        Procurementcontract contractQuery = new Procurementcontract();
        if(weightInterfaceParam==null){
            getWeightInterfaceParam();
        }

        Long orgid=weightInterfaceParam.getOrgId();  //通过接口参数表获取
        if (orgid==null){
            log.info("dont have orgId in weightinterfaceParam table");
            return false;
        }
        //当前参数设置的组织下的、状态为100、无供应商的
        // 关联查询qamain.type=2 淀粉薯采收合同
        contractQuery.setOrgId(orgid);
        contractQuery.setQamainType(2);
        contractQuery.setStatus(100);
        contractQuery.setSupplierId(Long.valueOf(-1));

        List<Procurementcontract> contractList = procurementcontractMapper.selectProcurementcontractList(contractQuery);
        if(contractList.size()==0){
            log.info("Cant find contract so we cant generate fo");
            return false;
        }
        Procurementcontract contract = contractList.get(0);
        //获取供应商
        String supplierName=weightData.getSupplier().trim();
        if(StringUtils.isBlank(supplierName)){
            log.info("Supplier name in weightData is blank");
            return false;
        }
        Supplier supplier = supplierMapper.selectSupplierByName(supplierName);

        if(supplier==null){
            //生成供应商
            supplier = generateSupplier(supplierName);
        }
        //生成货运单
        fromTudou(contract.getId(),null,supplier.getId(),null,contract,weightData,supplier, null);
        weightData.setBatch(weightInterfaceParam.getCode());
        return true;
    }

    private void getWeightInterfaceParam(){
        if(weightInterfaceParam==null){
            weightInterfaceParam  = new WeightInterfaceParam();
            List<WeightInterfaceParam> wl = weightInterfaceParamService.selectWeightInterfaceParamList(weightInterfaceParam);
            weightInterfaceParam = wl.get(0);
        }
    }
    /**
     * 生成供应商信息
     * @param supplierName
     * @return
     */
    @Transactional
    public Supplier generateSupplier(String supplierName){
        Supplier supplier = new Supplier();
        supplier.setName(supplierName);
        supplier.setShortname(supplierName);
        supplier.setStatus(1);
        supplier.setCreateBy(Long.valueOf(1)); //系统管理员
        supplier.setCreateTime(com.flow.service.utils.DateUtils.getNowDate());
        supplier.setType(1);
        supplier.setRemark("auto generated");
        supplierMapper.insertSupplier(supplier);
        return supplier;
    }
    @Transactional
    public AjaxResult fromTudou(Long contractid, String remark, Long supplierId, String fileIds,
                                Procurementcontract contract,WeightData weightData,Supplier supplier, Integer sellformPayType) {
        if (contract == null) {
            contract = procurementcontractMapper.selectProcurementcontractByCodeAndStatus(contractid);
        }

        if (contract.getStatus() == null) {
            return AjaxResult.error("合同状态异常");
        }
        Freightorder order = setFreightorderData(remark, contract);
        order.setSellformPayType(sellformPayType);
        if(weightData==null) {
            order.setDrivername("DRIVER");
            order.setDriverphone("TEL001");
            order.setCarcode("SYSTEM001");
        }else{
            //来源于过磅单接口
            order.setDrivername("DRIVER");
            order.setDriverphone("TEL001");
            order.setCarcode(weightData.getCarCode());
            order.setRemark(weightData.getCode());
        }

        // 写入供应商id
        //20230322 如果数据不是来源于接口且合同无供应商，则采用参数获取供应商
        // 否则，来源于接口的直接采用参数送进来的供应商信息
        if(weightData==null) {
            if (contract.getSupplierId() != null) {
                supplier = supplierMapper.selectSupplierById(contract.getSupplierId());
            } else {
                supplier = supplierMapper.selectSupplierById(supplierId);
            }
        }
        // 获取种植户名称 20230322 允许供应商不绑定用户
        if(!StringUtils.isBlank(supplier.getUserid())){
            SysUser user = sysUserMapper.selectUserByGuid(supplier.getUserid());
            order.setPlantorid(supplier.getUserid());
            order.setPlantor(user.getNickName());
            order.setPlantorphone(user.getPhonenumber());
        }

        order.setSupplierId(supplier.getId());
        order.setSupplierName(supplier.getName());


        SysUser operator = SecurityUtils.getLoginUser().getUser();

        if (weightData!=null) {
            //过磅单推送的数据，操作员信息从采收合同获取
            operator = sysUserMapper.selectUserByGuid(contract.getOperatorid());
        }
        order.setCreateBy(operator.getUserId());
        order.setOperatorid(operator.getGuid());
        order.setOperator(operator.getNickName());
        //送上来的数据如果已经是回皮、有净重了，写入货运单
        if(weightData!=null && weightData.getWeight()!=null){
            order.setHweight(weightData.getWeight());
        }

        freightorderMapper.insertFreightorder(order);
        //freightorder reset into weightData
        if(weightData!=null){
            weightData.setOrderCode(order.getCode());
            weightData.setOrderId(order.getId());
        }

        if (!checkContractWeight(contract.getGuid(), order.getGuid())) {
            throw  new CustomException("超过合同规定重量！");
//            return AjaxResult.error("超过合同规定重量！");
        }


        String msg = this.save(order, fileIds, operator);
        AjaxResult ajaxResult;
        if (msg.equals(ResultParam.SUCCESS)){
            ajaxResult = AjaxResult.success();
        }else{
            //ajaxResult = AjaxResult.error();
            //20230224 抛出异常，回滚
            throw  new CustomException("系统错误！");
        }
        ajaxResult.put("msg", msg);
        ajaxResult.put("data", order.getCode());
        return ajaxResult;
    }

    /**
     * 设置货运单数据
     *
     * @param remark
     * @param contract
     * @return
     */
    private Freightorder setFreightorderData(String remark, Procurementcontract contract) {
        Freightorder order = new Freightorder();
        // 写入部门信息
        SysDept sysDept = sysDeptMapper.selectDeptByGuid(contract.getDepartid());
        order.setDepartid(contract.getDepartid());
        order.setDeptId(sysDept.getDeptId());
        order.setDepartment(contract.getDepartname());
        // 写入组织id
        Organization organization = organizationMapper.selectOrganizationById(contract.getOrganizationid());
        order.setOrganizationid(contract.getOrganizationid());
        order.setOrgId(organization.getId());
        order.setOrgName(organization.getName());

        // 获取库房
        Storeroom sr = storeroomMapper.selectStoreroomByGuid(contract.getSrguid());
        // 获取地块
        if (StringUtils.isNotBlank(contract.getArealandid())) {
            TArealand area = arealandMapper.selectTArealandById(contract.getArealandid());
            order.setArealand(area.getAName());
        }
        // 获取品种
        Productinfo info = productinfoMapper.selectProductinfoById(contract.getProductguid());

        order.setIsdiscount(contract.getIsdiscount());
        order.setContractid(contract.getGuid());
        order.setArealandid(contract.getArealandid());
        order.setStoreroom(contract.getSrname());
        order.setProvence(sr.getProvince());
        order.setCity(sr.getCity());
        order.setCountry(sr.getArea());
        order.setStreet(sr.getAddress());
        order.setStrguid(sr.getGuid());
        order.setStrid(sr.getId());
        order.setCode(codeService.getCode("22"));
        order.setWghtperpkg(contract.getWghtperpkg());
        order.setVariety(info.getProductname());
        order.setProductinfoid(info.getGuid());
        if (StringUtils.isNotBlank(contract.getSetlwgtype())) {
            order.setSetlwgtype(contract.getPaymentmethod().toString());
        }
        /**
         * 2022年03月02日，如果是统一扣杂淀粉标准采收：从淀粉属定价表中获取单价
         */
        Qamain qamain = qamainService.selectQamainById(contract.getQamainid());
        if (qamain != null) {
            if ((contract.getIsdiscount() == 1 || contract.getIsdiscount() == 2 || contract.getIsdiscount() == 3) && 2 == qamain.getType()) {
                DpriceApply dprice = dpriceApplyMapper.selectEffectiveDprice(contract.getOrganizationid());
                if (dprice != null) {
                    order.setUnitPrice(dprice.getPrice());
                }
            }
        }
        order.setPrice(contract.getPrice());
        order.setDiscountrate(contract.getDiscountrate());
        order.setSoilchkrate(contract.getSoilchkrate());
        order.setUnqualifiedchkrate(contract.getUnqualifiedchkrate());
        order.setQatype(contract.getQatype());

        /**
         * 2021/2/3 xxl 写入规格
         */
        order.setSpecification(contract.getSpecificationname());
        order.setSpecificationid(contract.getSpecificationid());
        order.setSpguid(contract.getSpguid());

        order.setPaystatus(1);
        order.setCreatetime(DateUtils.getNowDate());
        order.setRemark(remark);
        order.setType(contract.getType());
        order.setFlowId(40L);
        order.setStatus(-1);
        String guid = IdUtils.fastSimpleUUID();
        order.setGuid(guid);
        //2023年09月05日，生成货运单时采收类型saleOrStore写入货运单harvest
        order.setHarvest(String.valueOf(contract.getSaleOrStore()));
        order.setPriceMethod(contract.getPriceMethod());
        return order;
    }

    /**
     * @return
     * @Author shaodong
     * @Description //扫码生成货运单时检查该合同下的货运单是否已经达标：
     * 生成的所有潜在生效的货运单（未删除、未拒收的所有货运单）重量和已经大于采收数量，则不生成货运单，给出提示（拉货通知拉货失败，重量超标）。
     * @Date 10:41 2021/4/28
     * @Param
     **/
    public boolean checkContractWeight(String guid, String orderid) {
        Procurementcontract contract = procurementcontractMapper.selectProcurementcontractById(guid);
        if (contract.getHarvestType() == 1) {
            return true;
        }
        BigDecimal contractWeight = contract.getWeight();
        if (contract.getWeight() == null) {
            return true;
        }
        BigDecimal weight = BigDecimal.ZERO;
        Freightorder freightorder = new Freightorder();
        freightorder.setContractid(contract.getGuid());
        freightorder.setNostats(new Integer[]{0});
        List<Freightorder> orders = freightorderMapper.selectFreightorderList(freightorder);
        for (int i = 0; i < orders.size(); i++) {
            Freightorder order = orders.get(i);
            if (order.getGuid().equalsIgnoreCase(orderid)) {
                continue;
            }
            if (order.getSetlwgtype().equals("1")) {
                weight = weight.add(order.getWeight() == null ? BigDecimal.ZERO : order.getWeight());
            }
            if (order.getSetlwgtype().equals("2")) {
                weight = weight.add(order.getHweight() == null ? BigDecimal.ZERO : order.getHweight());
            }
        }
        if (contractWeight.compareTo(weight) == 1) {
            return true;
        }
        return false;
    }

    public String save(Freightorder order, String fileIds, SysUser sysUser) {
        Contstandard cst = new Contstandard();
        cst.setContractid(order.getContractid());
        List<Contstandard> standards = contstandardMapper.selectContstandardList(cst);
        if (standards.size() > 0) {
            for (Contstandard standard : standards) {
                Forderstandard fos = new Forderstandard();
                fos.setForderid(order.getGuid());
                fos.setStandard(standard.getStandard());
                fos.setStandardid(standard.getStandardid());
                fos.setPrice(standard.getPrice());
                fos.setQaresult(BigDecimal.ZERO);
                fos.setGuid(IdUtils.fastSimpleUUID());
                forderstandardMapper.insertForderstandard(fos);
            }
        }


        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(order.getStrguid());
        order.setPlatformId(storeroom.getId());
//        FlowResult result = processUtils.defaultStart(processUtils.getStartNode(Long.valueOf(order.getFlowId())), order, fileIds
//                , sysUser);
        FlowResult result = processProxy.start(processUtils.getStartNode(Long.valueOf(order.getFlowId())), order, fileIds
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder sf = new Freightorder();
            sf.setStatus(result.getNextStat());
            sf.setGuid(order.getGuid());
            this.updateFreightorder(sf);
            return result.getMsg();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return result.getMsg();
        }
    }


    @Override
    public String saveLocation(String param) {
        JSONObject status = new JSONObject();
        try {
            Map<String, String> result = HarvestAnalysisUtils.analysis(param);
            JSONObject json = JSONObject.parseObject(result.get("param"));
            String token = result.get("token");
            // 验签
            Map<String, String> map = new HashMap<>();
            map.put("orderid", json.getString("orderid"));
            map.put("latitude", json.getString("latitude"));
            map.put("longitude", json.getString("longitude"));
            StringBuilder build = new StringBuilder();
            for (Map.Entry<String, String> en : map.entrySet()) {
                build.append(en.getKey() + "=" + en.getValue());
            }
            build.toString();
            String token2 = SecurityUtil.encode(MD5Utils.encryString(build.toString()));

            if (token.equals(token2)) {
                Freightorder order = freightorderMapper.selectFreightorderByOrdercode(json.getString("orderid"));
                if (StringUtils.isNotBlank(order.getArealandid())) {

                    String distance = setDistance(json.getString("latitude"), json.getString("longitude"),
                            order.getArealandid());
                    order.setDistance(distance);
                    order.setLatitude(json.getString("latitude"));
                    order.setLongitude(json.getString("longitude"));
                    freightorderMapper.updateFreightorder(order);

                    // 获取地块位置
                    Storeroom sr = storeroomMapper.selectStoreroomByGuid(order.getStrguid());

                    OpLocation location = new OpLocation();
                    location.setFocode(order.getCode());
                    location.setOpLatitude(json.getString("latitude"));
                    location.setOpLongitude(json.getString("longitude"));
                    String addResult = LocationCount.getAdd(location.getOpLongitude(), location.getOpLatitude());
                    JSONObject obj = JSONObject.parseObject(addResult);
                    JSONObject resultObj = obj.getJSONObject("result");
                    String address = resultObj.getString("formatted_address");
                    location.setAddress(address);
                    if (null != sr) {
                        if (StringUtils.isNotBlank(sr.getLatitude()) && StringUtils.isNotBlank(sr.getLongitude())
                                && StringUtils.isNotBlank(location.getOpLatitude())
                                && StringUtils.isNotBlank(location.getOpLongitude())) {
                            location.setTaLatitude(sr.getLatitude());
                            location.setTaLongitude(sr.getLongitude());
                            String distStr = LocationCount.getDistance(sr.getLatitude(), sr.getLongitude(),
                                    location.getOpLatitude(), location.getOpLongitude());
                            location.setDistance(distStr);
                        }
                    }
                    location.setOperationtype("1");
                    location.setGuid(IdUtils.fastSimpleUUID());
                    opLocationMapper.insertOpLocation(location);
                }
                status.put("status", "success");
            }
        } catch (Exception e) {
            e.printStackTrace();
            status.put("status", "error");
        } finally {
            return status.toString();
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult overWeightDT(Long id, Long taskid, String opinion, String fileIds, BigDecimal weight) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);

        if (!this.checkContractWeight(order.getContractid(), order.getGuid()) && order.getSetlwgtype().equals("1")) {
            return AjaxResult.error("weightout");//采收重量超出该合同约定重量

        }
        //装车付 未发起过支付申请的  过磅后可进行支付申请
        if (order.getPaystatus() >= 3) {
            return AjaxResult.error("付款申请已发起！");
        }
        Freightorder freightorder = new Freightorder();
        if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "1")) {//地头付款
            freightorder.setRatend(order.getDiscountrate());
            Procurementcontract contract = procurementcontractMapper.selectProcurementcontractById(order.getContractid());
            log.info("contract.getPrice(): "+contract.getPrice());
            freightorder.setActualSettl(contract.getPrice());
            freightorder.setRweight(weight);
            freightorder.setWeight(weight);
            //2023-09-05 地头过磅功能改造
            if (!StringUtils.equalsIgnoreCase("1", order.getHarvest())){
                freightorder.setPaystatus(2);//待支付申请
            }
            freightorder.setSettlement(weight.multiply(contract.getPrice())
                    .multiply(BigDecimal.ONE.subtract(freightorder.getRatend().divide(new BigDecimal(100)))).setScale(2, BigDecimal.ROUND_HALF_DOWN));
        }



        if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "2")) {//验收付款
            freightorder.setRweight(weight);
        }
        freightorder.setGuid(order.getGuid());
        freightorderMapper.updateFreightorder(freightorder);

        order.setPlatformId(order.getStrid());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, order
                , sysUser);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(order.getGuid());
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult overWeightYS(Long id, Long taskid, String opinion, String fileIds, BigDecimal weight) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);

        if (!this.checkContractWeight(order.getContractid(), order.getGuid()) && order.getSetlwgtype().equals("1")) {
            return AjaxResult.error("weightout");//采收重量超出该合同约定重量

        }
        //装车付 未发起过支付申请的  过磅后可进行支付申请
        if (order.getPaystatus() >= 3) {
            return AjaxResult.error("付款申请已发起！");
        }

        Freightorder freightorder = new Freightorder();
        freightorder.setGuid(order.getGuid());
        freightorder.setWeight(weight);
        freightorder.setPaystatus(2);
        if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "2")) {//验收付款
            freightorder.setRweight(weight);
        }

        Qaform qa = qaformService.selectQaformByLinkId(order.getGuid());
        List<Qaresult> qaresults = qaresultService.selectQaresultByLinkId(order.getGuid());
        qaresultService.calculateSinglePrice(order, qa, order.getAcceptStatus(), qaresults
                , null, null, 1);

        freightorderMapper.updateFreightorder(freightorder);
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(order.getStrguid());
        freightorder.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, order
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder pb = new Freightorder();
            pb.setStatus(result.getNextStat());
            pb.setGuid(order.getGuid());
            this.updateFreightorder(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whin(Long id, Long taskid, String opinion, String fileIds
            , BigDecimal hweight, BigDecimal pkgwgh, BigDecimal wghtperpkg, String sthguid) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);

        if (!this.checkContractWeight(order.getContractid(), order.getGuid()) && order.getSetlwgtype().equals("2")) {
            //20230907 修改为抛出异常
            throw new CustomException("采收重量超出该合同约定重量");
//            return AjaxResult.error("weightout");//采收重量超出该合同约定重量
        }
        BigDecimal netWeight;
        if (pkgwgh != null &&wghtperpkg != null && wghtperpkg.compareTo(BigDecimal.ZERO) != 0) {
            netWeight = hweight.multiply(BigDecimal.ONE.subtract(pkgwgh.divide(wghtperpkg, 6, BigDecimal.ROUND_HALF_UP))).setScale(6, BigDecimal.ROUND_HALF_UP);
        } else {
            netWeight = hweight;
        }

        //计算结算总金额
        if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "2")) {
            jiesuan(order, hweight, order.getSetlwgtype(), order.getActualSettl());
        }
        //20240119 修改，去掉sysuser参数
        //Whinform entity = prepareItemsWhin(sthguid, sysUser, order, netWeight);
        Whinform entity = prepareItemsWhin(sthguid,  order, netWeight);

//        entity.setPrice(priceRecover);
        //20240119 调用新的入库逻辑
//        String msg = whinformService.saveWhinfo(entity);
        whinformService.whin(entity, false);

        WeightSystemData systemData = new WeightSystemData();
        systemData.setCode(order.getCode());
        systemData = weightSystemDataMapper.getCurrentOne(systemData);
        if (systemData != null) {
            systemData.setStatus(2);
            weightSystemDataMapper.updateWeightSystemData(systemData);
        }

        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(order.getStrguid());
        order.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, order
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder fo = new Freightorder();
            fo.setGuid(order.getGuid());
            fo.setHweight(hweight);
            fo.setNetWeight(netWeight);
            fo.setPkgwgh(pkgwgh);
            fo.setWghtperpkg(wghtperpkg);
            fo.setWhinTime(DateUtils.getNowDate());
            fo.setPrice(order.getPrice());
            fo.setRatend(order.getRatend());
            fo.setIsdiscount(order.getIsdiscount());

            //jiesuan 放在入库之前调用，导致结算重量、付款申请状态有问题
            //20231007 补充数据
            if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "2")) {
                //jiesuan(order, hweight, order.getSetlwgtype(), order.getActualSettl());
                fo.setSettlement(order.getSettlement());
                fo.setActualSettl(order.getActualSettl());
                fo.setWeight(hweight);
                if (2 != order.getPriceMethod()){
                    fo.setPaystatus(2);//待支付申请
                }
            }


            fo.setStatus(result.getNextStat());
            fo.setGuid(order.getGuid());
            this.updateFreightorder(fo);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    //2023.09.06 采收订单的地头直销-自动完成采收入库
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whinAuto(Long id, BigDecimal hweight) {
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);
        Storehouseroom room = new Storehouseroom();
        room.setStoreguid(freightorder.getStrguid());
        room.setShrtype(1);
        //20230919 自动入库库间的选取，需要检查当前参数配置是否中转，不中转则取默认库间，中转，则通过auto_tranfer获取

        AutoTransfer cond = new AutoTransfer();
        cond.setFromOrgguid(freightorder.getOrganizationid());
        cond.setFromStrmguid(freightorder.getStrguid());
        AutoTransfer autoTransfer = autoTransferService.findAutoTransfer(cond);
        if(autoTransfer==null){
            //不中转，获取默认库间
            room = storehouseroomMapper.selectSHbySotreIdAndType(room);
        }else{
            room = storehouseroomMapper.selectStorehouseroomById(autoTransfer.getFromShguid());
        }

        if (null == room){
            throw new CustomException("采收库房没有配置原料库间!");
        }
        FlowTempNode node = new FlowTempNode();
        node.setOrderId(freightorder.getId());
//        node.setCreateBy(1L);
        node.setFlowId(freightorder.getFlowId());
        List<FlowTempNode> nodes = iFlowtempnodeService.getPendingNodes(node);

        return freightorderService.whin(id, nodes.get(0).getFlowTaskId(), "系统回调，自动完成", null, freightorder.getWeight(), null, null, room.getGuid());
    }

    /**
     * 结算-更新相关字段
     *
     * @param order
     * @param weight
     * @param setlwgtype  1、2-设置结算重量 3-不设置
     * @param actualSettl
     */
    private void jiesuan(Freightorder order, BigDecimal weight, String setlwgtype, BigDecimal actualSettl) {
        BigDecimal aWeight;
        order.setWeight(weight);
        order.setPaystatus(2);//待支付申请

        //2023-4-24 为了和亿茗过磅系统的单价和总金额匹配
        if (order.getIsdiscount() == 1 || order.getIsdiscount() == 2 ||
                order.getIsdiscount() == 3 || order.getIsdiscount() == 4) {
            aWeight = weight.multiply(BigDecimal.ONE.subtract(order.getRatend().divide(new BigDecimal(100)))).setScale(2, BigDecimal.ROUND_HALF_DOWN);
            order.setSettlement(aWeight.multiply(order.getPrice()).setScale(2, BigDecimal.ROUND_HALF_DOWN));
            order.setActualSettl(order.getSettlement().divide(weight, 2, BigDecimal.ROUND_HALF_DOWN));
        }else{

            order.setSettlement(weight.multiply(actualSettl).setScale(2, BigDecimal.ROUND_HALF_DOWN));
        }
    }

    /**
     * 采收-入库数据准备及入库
     *
     * @param sthguid
     * @param order
     * @param netWeight
     * @return
     */
    private Whinform prepareItemsWhin(String sthguid, Freightorder order, BigDecimal netWeight) {
        // 完善入库单信息
        Whinform entity = new Whinform();
        //2023-10-25 设置入库单明细总金额
        entity.setAmount(order.getSettlement());
        entity.setBusinesscode(order.getCode());
        entity.setFoguid(order.getGuid());
        entity.setStorermguid(order.getStrguid());
        entity.setStorehguid(sthguid);
        entity.setRemark("采收入库");
        entity.setProductid(order.getProductinfoid());
        entity.setProductname(order.getVariety());

        //获取吨的库存单位转换率，采收订单默认物料单位为 吨
        Stockunit stockunit4Ton = stockunitMapper.selectStockunitById(2L);
        //获取物料的库存单位转换率

        Salesspecification spe = new Salesspecification();
        if (StringUtils.isNotBlank(order.getSpguid())) {
            spe = salesspecificationMapper.selectSalesspecificationById(order.getSpguid());
        }
        //Stockunit stockunit = stockunitMapper.selectStockunitById(spe.getStockunitid());
        //20240119 调用新的入库逻辑，库存单位的转换交给WhinformServiceImpl的whin方法
        //BigDecimal newWeight = netWeight.multiply(stockunit4Ton.getToT()).divide(stockunit.getToT()).setScale(6, BigDecimal.ROUND_HALF_UP);
        //entity.setQty(newWeight);

        entity.setQty(netWeight);

        entity.setUnit(spe.getStockunit());
        //20240119 采收单价保留结算环节计算出来的采收单位单价： 元/吨
        //单价和数量的转换都在WhinformServiceImpl的whin方法中统一完成
        //入库单主表的price其实是没用的，采收订单继续保留，以防遗留代码仍然会用到 20230119
        BigDecimal rate = stockunitService.getRate(stockunit4Ton.getId(),spe.getStockunitid());
        //BigDecimal priceRecover = order.getActualSettl().multiply(netWeight).divide(entity.getQty(), 6,BigDecimal.ROUND_HALF_UP);
        entity.setPrice(order.getActualSettl().divide(rate).setScale(6, BigDecimal.ROUND_HALF_UP));;

        entity.setPuserguid(order.getPlantorid());
        entity.setPusername(order.getPlantor());
        entity.setCarcode(order.getCarcode());
        entity.setDrviername(order.getDrivername());
        entity.setDriverphone(order.getDriverphone());
        //20240119 不赋值，交给WhinformServiceImpl的whin方法处理
        //entity.setOperatorid(sysUser.getGuid());
//        entity.setCreateBy(sysUser.getUserId());
        //entity.setCreatedate(new Date());
        //entity.setFormno(codeService.getCode("4"));

        entity.setWhintype(1);
        Organization org = organizationMapper.selectOrganizationById(order.getOrganizationid());
        entity.setOrgguid(org.getGuid());
        entity.setOrgname(org.getName());
        entity.setSettlOrgId(org.getGuid());
        entity.setSettlOrgName(org.getName());
        //20230327修改供应商来源
//        Supplier supplier = supplierMapper.selectSupplierByUserid(order.getPlantorid());
        entity.setSupplierId(order.getSupplierId());
        entity.setSupplierName(order.getSupplierName());
        entity.setCurrency(1);
        //采收入库明细数据组装
        Whinformitem item = new Whinformitem();
        item.setSrguid(entity.getStorermguid());
        item.setShrguid(entity.getStorehguid());
        item.setProductguid(entity.getProductid());
        item.setOrgguid(entity.getOrgguid());
        item.setOrgname(entity.getOrgname());

        item.setPrice(order.getSettlement().divide(entity.getQty(), 6, RoundingMode.HALF_UP));
        //2023-10-25 设置入库单明细总金额
        item.setAmount(order.getSettlement());
        item.setSpguid(spe.getGuid());

        item.setWeight(entity.getQty());

        //20240119 设置单据业务单位 吨
        item.setBusinessUnitId(stockunit4Ton.getId());

        List<Whinformitem> items = new ArrayList<>();
        items.add(item);

        entity.setItems(items);
        return entity;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult whinBack(Long id, Long taskid, String opinion, String fileIds) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);

        //未发起支付申请 或者 已发起支付申请的地头付 可以反入库
        if (order.getPaystatus() <= 2 || (order.getPaystatus() > 2 && order.getSetlwgtype().equals("1"))) {
            //20240125 反入库改造通用方法
//            this.whinBack(sysUser, order, fileIds, opinion, taskid);
            if (order.getSetlwgtype().equals("2")) {//验收付反入库后 支付状态为初始
                Freightorder fo = new Freightorder();
                fo.setGuid(order.getGuid());
                fo.setPaystatus(1);
                fo.setHweight(BigDecimal.ZERO);
                this.updateFreightorder(fo);
            }
            whinformService.newWhinBack(sysUser, order.getGuid());

            Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(order.getStrguid());
            order.setPlatformId(storeroom.getId());
            FlowResult result = processProxy.approval(taskid, fileIds, opinion, order
                    , sysUser);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Freightorder pb = new Freightorder();
                pb.setStatus(result.getNextStat());
                pb.setGuid(order.getGuid());
                this.updateFreightorder(pb);
                return AjaxResult.success();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error(result.getMsg());
            }
        } else {
            //已经申请支付不能退回，请先操作支付退回!
            return AjaxResult.error("已发起付款申请的订单不允许反入库");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult confirm(Long id, Long taskid, String opinion, String fileIds, Integer refuseFlag
            , String cartype, BigDecimal price, BigDecimal unitPrice) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);
        Freightorder pb = new Freightorder();
        pb.setGuid(order.getGuid());

        pb.setRefuseFlag(refuseFlag);
        pb.setCartype(cartype);
        log.info("refuseFlag: " + refuseFlag);
        log.info("order.getPaystatus(): " + order.getPaystatus());
        if (refuseFlag == 2) {//已发起付款申请的单子 不允许 拒绝
            if (order.getPaystatus() > 2) {
                return AjaxResult.error("已发起付款申请的单子不允许拒绝!");
            }
        }
        if (StringUtils.equalsIgnoreCase(order.getSetlwgtype(), "2")) {//验收付款
            int flag = 0;
            if (StringUtils.isNotNull(price)) {
                flag = 1;
                pb.setPrice(price);
            }
            if (StringUtils.isNotNull(unitPrice)) {
                flag = 2;
                pb.setUnitPrice(unitPrice);
            }
            Qaform qa = qaformService.selectQaformByLinkId(order.getGuid());
            List<Qaresult> qaresults = qaresultService.selectQaresultByLinkId(order.getGuid());
            //淀粉属合同单价：有按照此单价计算，不按照unitpRICE计算；设置一个flag，看是按照合同单价还是淀粉含量单价计算
            qaresultService.calculateSinglePrice(order, qa, order.getAcceptStatus(), qaresults
                    , price, unitPrice, flag);
        }

        this.updateFreightorder(pb);//更新拒绝标识参数到数据库，流程需要根据此参数走条件流程
        Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(order.getStrguid());
        order.setPlatformId(storeroom.getId());
        FlowResult result = processProxy.approval(taskid, fileIds, opinion, order
                , sysUser);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Freightorder freightorder = new Freightorder();
            freightorder.setGuid(order.getGuid());
            freightorder.setStatus(result.getNextStat());
            this.updateFreightorder(freightorder);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult quality(Long id, Long taskid, String opinion, String fileIds, Integer refuseFlag
            , BigDecimal deductRateByHand/*, Qaform qaform*/) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Freightorder order = freightorderMapper.selectFreightorderByAutoId(id);
        if (refuseFlag == 2) {//已发起付款申请的单子 不允许 拒绝
            if (order.getPaystatus() > 2) {
                return AjaxResult.error("已发起付款申请的单子不允许拒绝!");
            }
        }

        /*if (null != unitPrice) {
            if (order.getUnitPrice().compareTo(unitPrice) != 0) {
                if (StringUtils.isBlank(opinion)) {
                    opinion = "淀粉单价由" + order.getUnitPrice() + "调整为" + unitPrice;
                } else {
                    opinion = opinion + "  淀粉单价由" + order.getUnitPrice() + "调整为" + unitPrice;
                }
            }
        }*/

        //验收付的货运单，允许手工录入扣杂率
        if (StringUtils.isNotNull(deductRateByHand)) {
            if (null != order.getDiscountrate()) {
                if (order.getDiscountrate().compareTo(deductRateByHand) == 1) {
                    return AjaxResult.error("录入的扣杂率小于合同扣杂率！");
                }
            }
            order.setDeductRateByHand(deductRateByHand);
        }

        order.setRefuseFlag(refuseFlag);
        if (2 == order.getType()) {
            int result = qaresultService.setQaresult(order, sysUser.getGuid()/*, unitPrice*/);
            if (4 == result) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("质检失败！");
            }
            order.setAcceptStatus(result);
            this.updateFreightorder(order);
        } else {
            order.setAcceptStatus(1);
            this.updateFreightorder(order);
        }
        Qaform qa = qaformService.selectQaformByLinkId(order.getGuid());
        qaresultService.calculateRatend(order, qa);

        return qaformService.updateOrder(order.getGuid(), opinion, sysUser, fileIds, "1", taskid);
    }

    @Override
    public AjaxResult getQaItems(Long id) {
        Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);
        List<Qaitems> qaitems = qarecordService.getQaItemsMain(freightorder);
        return AjaxResult.success(qaitems);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult updateRecord(Qarecord qarecord) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        String foguid = qarecord.getFoguid();
        Freightorder order = freightorderMapper.selectFreightorderById(foguid);

        List<Qaitems> qaitems = qarecordService.getQaItemsMain(order);
        List<Qarecord> records = qarecordService.selectQarecordListByFoguid(foguid);
        BigDecimal mixweight = calculateMixweight(qarecord, qaitems, order);

        //将本次记录添加到历史记录中，计算
        qarecord.setOperatorid(sysUser.getTuserId());
        qarecord.setMixweight(mixweight);
        if (StringUtils.isBlank(qarecord.getGuid())) {
            qarecord.setQanumbers(records.size());
        }

        qarecordService.addOrUpdate(qarecord);

        Qaform qaform = qaformService.selectQaformByLinkId(order.getGuid());
        if (qaform == null) {
            qaformService.addOrUpdateQaform(qaform, order, sysUser);
        }
        qarecordService.updateQAform(foguid);
        if (order.getIsdiscount() == 4) {
            qarecordService.addForderStandard(order);
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult discharge(Long id, String param) {
        AjaxResult resultWlI = AjaxResult.success();
        if (StringUtils.isNotNull(id)) {// 土豆集提交
            SysUser sysUser = SecurityUtils.getLoginUser().getUser();
            Freightorder freightorder = freightorderMapper.selectFreightorderByAutoId(id);
            if (freightorder.getStatus() >= 20 && "1".equalsIgnoreCase(freightorder.getSetlwgtype()) && freightorder.getWeight() == null) {
                return AjaxResult.error("卸货失败：订单未过磅");
            } else {
                /**
                 * @auther shaodong
                 * @desc 采收订单为删除与拒收时，可以卸货更新瑞通物流的单子，达到再次扫码拉货的目的
                 * @Date 14:21 2020/5/22
                 **/
                Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
                freightorder.setPlatformId(storeroom.getId());
                FlowResult result = processProxy.approvalByNodeType(40L, 5, freightorder, sysUser);

                if (result.getMsg().equals(ResultParam.SUCCESS)) {
                    if (StringUtils.isNotEmpty(freightorder.getOrdercode())){
                        String wlResult = this.xiehuo(freightorder.getOrdercode());
                        if (wlResult.startsWith("success")) {
                            Freightorder pb = new Freightorder();
                            pb.setStatus(result.getNextStat());
                            pb.setGuid(freightorder.getGuid());
                            pb.setUnloadtime(new Date());
                            this.updateFreightorder(pb);
                            resultWlI.put("status", "success");
                            return resultWlI;
                        } else {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            resultWlI.put("status", "卸货失败：审批");
                            return resultWlI;
                        }
                    }else{
                        Freightorder pb = new Freightorder();
                        pb.setStatus(result.getNextStat());
                        pb.setGuid(freightorder.getGuid());
                        pb.setUnloadtime(new Date());
                        this.updateFreightorder(pb);
                        return AjaxResult.success();
                    }

                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error(result.getMsg());
                }
            }
        } else {
            Map<String, String> resultWl = HarvestAnalysisUtils.analysis(param);
            JSONObject json = JSONObject.parseObject(resultWl.get("param"));
            String token = resultWl.get("token");
            // 验签
            Map<String, String> map = new HashMap<>();
            map.put("orderid", json.getString("orderid"));
            StringBuilder build = new StringBuilder();
            for (Map.Entry<String, String> en : map.entrySet()) {
                build.append(en.getKey() + "=" + en.getValue());
            }
            log.debug("扫码卸货： " + build.toString());
            String token2 = null;
            try {
                token2 = SecurityUtil.encode(MD5Utils.encryString(build.toString()));
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (token.equals(token2)) {
                String wlordercode = json.getString("orderid");
                SysUser sysUser = sysUserMapper.selectUserById(1L);
                Freightorder freightorder = freightorderMapper.selectFreightorderByOrdercode(wlordercode);
                Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(freightorder.getStrguid());
                freightorder.setPlatformId(storeroom.getId());
                if (!processUtils.getStartNodeByType(40L, 5, freightorder.getStatus())) {
                    resultWlI.put("status", "卸货失败：非卸货状态");
                    return resultWlI;
                }

                FlowResult result = processProxy.approvalByNodeType(40L, 5, freightorder, sysUser);

                if (result.getMsg().equals(ResultParam.SUCCESS)) {

                    String wlResult = this.xiehuo(freightorder.getOrdercode());
                    if (wlResult.startsWith("success")) {
                        Freightorder pb = new Freightorder();
                        pb.setStatus(result.getNextStat());
                        pb.setGuid(freightorder.getGuid());
                        pb.setUnloadtime(new Date());
                        this.updateFreightorder(pb);
                        resultWlI.put("status", "success");
                        return resultWlI;
                    } else {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        resultWlI.put("status", "卸货失败");
                        return resultWlI;
                    }
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    resultWlI.put("status", "卸货失败：审批");
                    return resultWlI;
                }
            } else {
                resultWlI.put("status", "卸货失败：接口验证");
                return resultWlI;
            }
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult delRecord(String guid) {
        Qarecord qarecord = qarecordService.selectQarecordById(guid);
        qarecordService.deleteQarecordById(guid);
        Freightorder freightorder = freightorderMapper.selectFreightorderById(qarecord.getFoguid());
        if (freightorder.getIsdiscount() == 4) {
            qarecordService.addForderStandard(freightorder);
        }
        qarecordService.updateQAform(qarecord.getFoguid());
        return AjaxResult.success();
    }

    /**
     * @return guid 物流订单GUID
     * @auther shaodong
     * @desc 土豆集点击扫码卸货，更新物流订单接口
     * @Date 14:16 2020/8/20
     * @Param []
     **/
    public String xiehuo(String guid) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("guid", guid);
        Map<String, String> resultmap = HttpBusinessUtils.harvestPost(map, DwlConfig.getWebPath() + "/weixin/Erweima!xiehuo.action");
        String result = resultmap.get("result");
        JSONObject js = JSONObject.parseObject(result);
        String re = js.getString("result");
        return re;
    }

    /**
     * 计算杂土重量
     *
     * @param qaitems 1-土杂 2-不合格项 3-普通合格项 4-淀粉薯含量 5-干物质
     * @return
     */
    private BigDecimal calculateMixweight(Qarecord qarecord, List<Qaitems> qaitems, Freightorder order) {

        Procurementcontract contract = procurementcontractMapper.selectProcurementcontractById(order.getContractid());
        Qamain qamain = qamainService.selectQamainById(contract.getQamainid());

        //前台直接设置对应的item1weight
        BigDecimal mixweight = BigDecimal.ZERO;
        BigDecimal itemnumweight = BigDecimal.ZERO;
        for (int i = 0; i < qaitems.size(); i++) {
            BigDecimal itemwight = qarecord.getItemWeight(i);
            if (itemwight == null) {
                itemwight = new BigDecimal(0);
            }
            if (order.getIsdiscount() == 6) {//优质优价从质检相中获取土杂重量
                Qastandard qastandard = qastandardMapper.selectQastandardById(qaitems.get(i).getQastandard());
                if (1 == qastandard.getType()) {
                    return itemwight;
                }
            }
            if ((order.getIsdiscount() == 1 || order.getIsdiscount() == 2 || order.getIsdiscount() == 3) && 2 == qamain.getType()) {//统一扣杂、淀粉属标准
                Qastandard qastandard = qastandardMapper.selectQastandardById(qaitems.get(i).getQastandard());
                if (4 == qastandard.getType() || 5 == qastandard.getType()) {
                    itemwight = BigDecimal.ZERO;
                }
            }
            itemnumweight = itemnumweight.add(itemwight);
        }
        BigDecimal itemokwight = qarecord.getOkweight();
        if (itemokwight == null) {
            itemokwight = new BigDecimal(0);
        }
        BigDecimal itemtotlwight = qarecord.getTotalweight();
        if (itemtotlwight == null) {
            itemtotlwight = new BigDecimal(0);
        }
        mixweight = itemtotlwight.subtract(itemnumweight).subtract(itemokwight);
        return mixweight;
    }

    private void whinBack(SysUser sysUser, Freightorder order, String fileIds, String opinion, Long taskid) {
        if (order.getSetlwgtype().equals("2")) {//验收付反入库后 支付状态为初始
            Freightorder fo = new Freightorder();
            fo.setGuid(order.getGuid());
            fo.setPaystatus(1);
            fo.setHweight(BigDecimal.ZERO);
            this.updateFreightorder(fo);
        }
        //查询入库单
        Whinform inform = new Whinform();
        inform.setFoguid(order.getGuid());
        List<Whinform> informs = whinformService.selectWhinformList(inform);
        inform = informs.get(0);

        //查询入库单明细
        Whinformitem item = new Whinformitem();
        item.setWhinid(inform.getGuid());
        List<Whinformitem> items = whinformitemMapper.selectWhinformitemList(item);

        //反向生成入库单
        inform.setGuid("");
        inform.setFormno(codeService.getCode("4"));
        inform.setOperatorid(sysUser.getGuid());
        inform.setRemark("反向生成入库单！");
        inform.setQty(inform.getQty().negate());
        String guid = IdUtils.fastSimpleUUID();
        inform.setGuid(guid);
        inform.setCreatedate(DateUtils.getNowDate());
        whinformService.insertWhinform(inform);

        for (Whinformitem it : items) {
            it.setGuid(IdUtils.fastSimpleUUID());
            it.setWhinid(guid);
            it.setWeight(it.getWeight().negate());
            it.setCreateTime(DateUtils.getNowDate());
            it.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whinformitemMapper.insertWhinformitem(it);

            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(it.getShrguid());

            // 更新库存信息
            Whinfo info;
            if (house.getShrtype() == 1) {//1-原材料库，2-产成品库 3-废品库（不合格品库）
                info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(),
                        it.getShrguid(), null);
            } else {
                info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(),
                        it.getShrguid(), it.getSpguid());
            }
            if (info != null) {
                Whinfo upinfo = new Whinfo();
                upinfo.setGuid(info.getGuid());
                upinfo.setStoreqty(info.getStoreqty().add(it.getWeight()));
                whinfoService.updateWhinfo(upinfo);
            }
        }
    }

    /**
     * @param @param     Qty 净重 @param @param price 单价 @param
     * @param deductrate 扣杂率
     * @param @return
     * @return BigDecimal @throws
     * @Title: getSettlement
     * @Description: 计算结算金额 结算金额=净重*（1-扣杂率）*单价（合同）
     */
    public BigDecimal getSettlement(BigDecimal Qty, BigDecimal price, BigDecimal deductrate) {
        BigDecimal one = new BigDecimal(1);
        BigDecimal rate = one.subtract(deductrate.divide(new BigDecimal(100)));
        return rate.multiply(Qty).multiply(price);
    }

    /**
     * 当前扫码所在位置
     *
     * @return 地块guid
     */
    public String setDistance(String latitude, String longitude, String guid) throws Exception {
        TArealand arealand = arealandMapper.selectTArealandById(guid);
        if (StringUtils.isNotBlank(arealand.getLongitude())
                && StringUtils.isNotBlank(arealand.getLatitude())) {
            String distStr = LocationCount.countDistance(latitude, longitude, arealand.getLatitude(),
                    arealand.getLongitude());
            return distStr;
        }
        return "";
    }

    @Override
    public BasePojo getBaseById(Long id) {
        return selectFreightorderDetailByAutoId(id);
    }

    @Override
    public BasePojo getBaseByCode(String code) {
        return freightorderMapper.selectFreightorderByCode(code);
    }

    @Override
    public boolean validateForToSpecialNode(CallBackParameterWrapper cbpw){
        Freightorder order = selectFreightorderDetailByAutoId(cbpw.getBase().getId());
        if (order.getPaystatus() <= 2 || (order.getPaystatus() > 2 && order.getSetlwgtype().equals("1"))) {
            return true;
        }else{
            FlowResult flowResult = cbpw.getFlowResult();
            flowResult.setMsg("已发起付款申请的订单不允许回退");
            cbpw.setFlowResult(flowResult);
            return false;
        }
    }
}
